import { BaseTexture } from "@pixi/core";
import { clamp, inNeteaseAppFamily, removeElement, uuid } from "./common";

export async function createVideoElement(url: string): Promise<HTMLVideoElement> {
    return new Promise((resolve, reject) => {
        let video = document.createElement("video");
        video.src = url;
        video.loop = false;
        video.autoplay = false;
        video.muted = true;
        video.volume = 0.0;
        video.controls = false;
        video.crossOrigin = "anonymous"
        video.playsInline = true;
        video.setAttribute('webkit-playsinline', 'true')
        video.id = uuid();
        video.preload = "metadata";
        video.style.display = "none";

        video.addEventListener('loadedmetadata', () => {
            resolve(video)
        })
        video.addEventListener('error', reject)
        document.getElementsByTagName('body')?.[0]?.appendChild?.(video);
    })
}

export function createVideoBaseTexture(video: HTMLVideoElement) {
    const base = BaseTexture.from(video, {
        resourceOptions: {
            autoPlay: false,
            loop: false,
        }
    })

    const destroy = base.destroy.bind(base);
    return Object.assign(base, {
        destroy() {
            destroy();
            removeElement(video);
        }
    })
}

export async function playVideo(video: HTMLVideoElement, retry = true) {
    const id = video.id;

    const jsVideoPlay = async () => {
        const promise = video.play()
        if (promise instanceof Promise) {
            await promise
        }
    }

    try {
        if (inNeteaseAppFamily() && id) {
            // @ts-ignore
            let mnb: any = {}

            if (!mnb.rpcVideoPlay) {
                mnb.addMethod({
                    schema: 'html.video.play',
                    name: 'rpcVideoPlay',
                });
            }
            await mnb.rpcVideoPlay({ id });
        } else {
            await jsVideoPlay()
        }
    } catch (e) {
        if (retry) {
            await playVideo(video, false);
        } else {
            throw e;
        }
    }
}

export function setVideoSpeed(video: HTMLVideoElement, speed: number) {
    if (!video) {
        return;
    }
    video.playbackRate = clamp(speed, 0.25, 4);
}

export function fastSeekMs(video: HTMLVideoElement, timeMs: number) {
    const duration = video.duration;

    const time = clamp(timeMs / 1000, 0, duration);
    video.currentTime = time;
}